package com.qumitech.visualnovel.service.account.impl;

import com.alibaba.fastjson.JSONObject;
import com.qumitech.visualnovel.component.exception.BusinessException;
import com.qumitech.visualnovel.component.util.*;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.ResultEnum;
import com.qumitech.visualnovel.datasource.app.AccountMapper;
import com.qumitech.visualnovel.model.dao.app.Account;
import com.qumitech.visualnovel.model.dao.console.UserInfo;
import com.qumitech.visualnovel.model.common.UrlConstant;
import com.qumitech.visualnovel.pubdef.dto.realinfo.UserRealInfoAdminUpdateDTO;
import com.qumitech.visualnovel.pubdef.dto.user.AccountBindDTO;
import com.qumitech.visualnovel.service.account.AccountService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * AccountService 实现类
 * @author bke
 * @date 2018/11/26 10:36
 */
@Service
public class AccountServiceImpl implements AccountService {

    private final Logger Log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    AccountMapper accountMapper;

    private static final String ACCOUNT_ADMIN_URL = "/account/admin";

    @Override
    public Map<String, Object> getChannelsAndVersions() {
        String url = UrlConstant.SERVER_URL + ACCOUNT_ADMIN_URL +  "/channels";
        String body = HttpInvokeUtil.httpGet(url, null, null);
        BaseRsp rsp = JSONObject.parseObject(body, BaseRsp.class);
        if (rsp == null || rsp.getStatus() != ResultEnum.SUCCESS.getState() || rsp.getData() == null) {
            throw new BusinessException(ResultEnum.FAILURE);
        }
        Map<String, Object> rspMap = (Map<String, Object>) rsp.getData();
        if (rspMap.get("channels") == null || rspMap.get("versions") == null) {
            throw new BusinessException(ResultEnum.FAILURE);
        }
        return rspMap;
    }

    @Override
    public String getOperatorName() {
        Subject subject = SecurityUtils.getSubject();
        UserInfo activeUser = (UserInfo) subject.getPrincipal();
        return activeUser.getUsername();
    }

    @Override
    public BaseRsp listUserRealInfoAdmin(Map<String, String> paramMap) {
        String url = UrlConstant.SERVER_URL + ACCOUNT_ADMIN_URL + "/realinfo";
        String body = HttpInvokeUtil.httpGet(url, paramMap, null);
        return JSONObject.parseObject(body, BaseRsp.class);
    }

    @Override
    public BaseRsp updateUserRealInfoAdmin(UserRealInfoAdminUpdateDTO updateDTO) {
        updateDTO.setOperator(getOperatorName());
        String url = UrlConstant.SERVER_URL + ACCOUNT_ADMIN_URL + "/realinfo";
        String req = JSONObject.toJSONString(updateDTO);
        String body = HttpInvokeUtil.httpPutJson(url, req, UrlConstant.DefaultEncode, null);
        return JSONObject.parseObject(body, BaseRsp.class);
    }

    @Override
    public List<Account> getList(List<String> uids) {
        return accountMapper.getList(uids);
    }

    @Override
    public List<Account> getPresentList(List<String> presentIds) {
        return accountMapper.getPresentList(presentIds);
    }

    @Override
    public List<String> importUser(MultipartFile file) {
        Map<Integer, Map<Integer, Object>> map = new HashMap<>(16);
        try {
            map = ExcelUtil.readExcelContentz(file);
        } catch (Exception e) {
            Log.error("[importUser] import excel fail, {}", e);
        }

        List<String> userIds = new ArrayList<>(16);
        for (Integer key : map.keySet()) {
            Map<Integer, Object> user = map.get(key);
            try {
                userIds.add(user.get(0).toString().split("\\.")[0]);
            } catch (Exception e) {
                Log.error("[importUser] add User fail. name:{}, error:{}", user, e);
            }
        }
        return userIds;
    }

    @Override
    public Map<String, Object> exportUserIds(HttpServletResponse request, List<String> uids) {
        Map<String, Object> resultMap = new HashMap<>(16);
        try {
            List<Account> accounts = accountMapper.getList(uids);
            if (accounts.size() < 1) {
                accounts = accountMapper.getPresentList(uids);
            }

            ExcelUtils<Account> xls = new ExcelUtils<>(Account.class);
            String filename = FileUtil.getExcelName();
            request.reset();
            request.setContentType("application/vnd.ms-excel;charset=utf-8");
            request.setHeader("Content-Disposition", "attachment;filename=" + filename);
            OutputStream outputStream = request.getOutputStream();
            xls.exportExcel("用户ID转换", accounts, outputStream);
            outputStream.flush();
            outputStream.close();
            resultMap.put("title", filename);
            return resultMap;
        } catch (IOException e) {
            e.printStackTrace();
        }

        throw new BusinessException(ResultEnum.EXCEL_EXPORT_ERROR);
    }

    @Override
    public void bindOldAccount(AccountBindDTO bindDTO) {
        String url = UrlConstant.SERVER_URL + ACCOUNT_ADMIN_URL + "/bind";
        String req = JSONObject.toJSONString(bindDTO);
        HttpInvokeUtil.httpPutJson(url, req, UrlConstant.DefaultEncode, null);
    }
}
